#include "Renderer.h"
#include "Beam.h"
#include <assert.h>
#include <iostream>

Renderer::Renderer(void)
	:
	m_initialized(false),
	m_mainWindow(0),
	m_renderer(0)
{
	Initialize();
}
Renderer::~Renderer(void)
{
	Shutdown();
}
void Renderer::Initialize(void)
{
	if (m_initialized == true)
	{
		return;
	}
	if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
	{
		return;
	}
	if (TTF_Init() != -1)
	{
		m_font = TTF_OpenFont("FreeSans.ttf", 20);
	}


	m_mainWindow = SDL_CreateWindow("SDL Test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
	if (m_mainWindow == 0)
	{
		return;
	}
	m_renderer = SDL_CreateRenderer(m_mainWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
	if (m_renderer == 0)
	{
		return;
	}
	m_initialized = true;
}
void Renderer::Shutdown()
{
	if (m_renderer)
	{
		SDL_DestroyRenderer(m_renderer);
	}
	if (m_mainWindow)
	{
		SDL_DestroyWindow(m_mainWindow);
	}
	if (m_font)
	{
		TTF_CloseFont(m_font);
	}
	if (m_initialized == true)
	{
		TTF_Quit();
		SDL_Quit();
	}
}
SDL_Texture* Renderer::LoadTexture(const char* path)
{
	SDL_Surface* bmp = SDL_LoadBMP(path);
	if (bmp != 0)
	{
		SDL_Texture* texture = SDL_CreateTextureFromSurface(m_renderer, bmp);
		SDL_FreeSurface(bmp);
		return texture;
	}
	return 0;
}
void Renderer::FreeTexture(SDL_Texture* texture)
{
	SDL_DestroyTexture(texture);
}
void Renderer::DrawObject(GameObject& object)
{
	if (object.GetPosition().x <= 0 || object.GetPosition().y <= 0)
		return;
	if (object.GetObjType() == OBJECT_TYPE::BEAM)
	{
		Beam& beam = (Beam&)object;
		Position& pos1 = beam.GetSource()->GetPosition();
		Position& pos2 = beam.GetTarget()->GetPosition();
		SDL_SetRenderDrawColor(m_renderer, 100,100,100, 0);
		SDL_RenderDrawLine(m_renderer, pos1.x, pos1.y, pos2.x, pos2.y);
		SDL_SetRenderDrawColor(m_renderer, 0,0,0,0);
	}
	else
	{
		SDL_Texture* texture = object.GetTexture();
		SDL_Rect& rect = (SDL_Rect&)object.GetPosition();
		int ret = SDL_RenderCopy(m_renderer, texture, 0, &rect);
		assert(ret != -1);
	}
}
void Renderer::DrawBackground(SDL_Texture* background)
{
	if (background)
	{
		SDL_RenderCopy(m_renderer, background, 0, 0);
	}
}
void Renderer::PrintText(const char* text, int x, int y, int size)
{
	assert(m_font);

	SDL_Surface* surface = 0;
	SDL_Color color = {255,255,255};
	surface = TTF_RenderText_Solid(m_font, text, color);

	assert(surface);

	SDL_Texture* tex=SDL_CreateTextureFromSurface(m_renderer, surface);
	SDL_Rect rect = {0};
	rect.x = x;
	rect.y = y;
	rect.h = size;
	rect.w = size * (strlen(text) / 2);
	SDL_RenderCopy(m_renderer, tex, 0, &rect);
	SDL_FreeSurface(surface);
	SDL_DestroyTexture(tex);
}
void Renderer::Render(void)
{
	SDL_RenderPresent(m_renderer);
}
void Renderer::Clear(void)
{
	SDL_RenderClear(m_renderer);
}
bool Renderer::IsInitialized(void)
{
	return m_initialized;
}
Renderer& Renderer::GetInstance(void)
{
	static Renderer renderer;
	return renderer;
}
SDL_Renderer* Renderer::GetRenderer(void)
{
	return m_renderer;
}